home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-06 | 9.1 KB | 356 lines | [TEXT/ALFA] |
- #############################################################################
- #############################################################################
- #
- # latexSmart.tcl (called from latex.tcl)
- #
- # Smart quotes, dots, subscripts, superscripts, and fillParagraph
- #
- #############################################################################
- #
- # Original author unknown
- #
- # Maintainer: Tom Scavo <trscavo@syr.edu>
- #
- # Fill routines by: Vince Darley <vince@das.harvard.edu>
- #
- #############################################################################
- #############################################################################
-
- #--------------------------------------------------------------------------
- # Smart quotes:
- #--------------------------------------------------------------------------
-
- proc smartDQuote {} {
- global TeXmodeVars
- if {[isSelection]} { deleteSelection }
- if { !$TeXmodeVars(smartQuotes) || [literalChar] } { insertText {"}; return }
- if {[leftQ]} {
- insertText {``}
- } else {
- insertText {''}
- }
- }
-
- # bind double quote:
- ascii 0x22 <s> smartDQuote TeX
-
- proc smartQuote {} {
- global TeXmodeVars
- if {[isSelection]} { deleteSelection }
- if { !$TeXmodeVars(smartQuotes) || [literalChar] } { insertText {'}; return }
- if {[leftQ]} {
- insertText {`}
- } else {
- insertText {'}
- }
- }
-
- # bind single quote:
- ascii 0x27 smartQuote TeX
-
- proc leftQ {} {
- if { [getPos] == 0 } { return 1 };
- set q [lookAt [expr [getPos]-1]]
- case $q in {
- {\t} {return 1}
- {(} {return 1}
- {\{} {return 1}
- {[} {return 1}
- {<} {return 1}
- {\ } {return 1}
- {\r} {return 1}
- }
- return 0
- }
-
- #--------------------------------------------------------------------------
- # Smart dots:
- #--------------------------------------------------------------------------
-
- proc smartDots {} {
- global TeXmodeVars
- if {[isSelection]} { deleteSelection }
- if { !$TeXmodeVars(smartDots) || [literalChar] } { insertText {.}; return }
- if {[lookAt [expr [set endPos [getPos]]-1]] == "."} then {
- if {[lookAt [set begPos [expr $endPos-2]]] == "."} then {
- replaceText $begPos $endPos "\\ldots"
- } else {
- insertText "."
- }
- } else {
- insertText "."
- }
- }
-
- # bind period:
- ascii 0x2e smartDots "TeX"
-
- #--------------------------------------------------------------------------
- # Smart subscripts and superscripts:
- #--------------------------------------------------------------------------
-
- proc smartSubscripts {} {
- smartScripts {_}
- }
-
- proc smartSuperscripts {} {
- smartScripts {^}
- }
-
- proc smartScripts {char} {
- global TeXmodeVars
- if {[isSelection]} { deleteSelection }
- if { !$TeXmodeVars(smartScripts) || [literalChar] } then {
- insertText $char
- return
- }
- if { $TeXmodeVars(smartScripts) } then {
- if { $char == {_} } {subscript} {superscript}
- }
- }
-
- # bind underscore and caret:
- ascii 0x5f <s> smartSubscripts "TeX"
- ascii 0x5e <s> smartSuperscripts "TeX"
-
- #--------------------------------------------------------------------------
- # Escapes and exceptions:
- #--------------------------------------------------------------------------
-
- proc literalChar {} {
- return [expr {[lookAt [expr [getPos] - 1]] == "\\"}]
- }
-
- proc escapeSmartStuff {} {
- if {![isSelection]} then {
- set pos [getPos]
- # Escape double quotes:
- if { $pos > 1 } then {
- set pos2 [expr $pos - 2]
- if { [getText $pos2 $pos] == "''" } then {
- replaceText $pos2 $pos {"}
- return
- } elseif { [getText $pos2 $pos] == "``" } then {
- replaceText $pos2 $pos {"}
- return
- }
- }
- # Escape single quote:
- if { $pos > 0 } then {
- set pos1 [expr $pos - 1]
- if { [lookAt $pos1] == "`" } then {
- backSpace
- insertText {'}
- return
- }
- }
- # Escape dots:
- if { $pos > 5 } then {
- set pos6 [expr $pos - 6]
- if { [getText $pos6 $pos] == "\\ldots" } then {
- replaceText $pos6 $pos {...}
- return
- }
- }
- # Escape underscore:
- if { $pos > 1 && [maxPos] > [expr $pos + 1] } then {
- set begPos [expr $pos - 2]
- set endPos [expr $pos + 2]
- if { [getText $begPos $endPos] == "_\{\}Ñ" } then {
- replaceText $begPos $endPos {_}
- return
- }
- }
- # Escape caret:
- if { $pos > 1 && [maxPos] > [expr $pos + 1] } then {
- set begPos [expr $pos - 2]
- set endPos [expr $pos + 2]
- if { [getText $begPos $endPos] == "^\{\}Ñ" } then {
- replaceText $begPos $endPos {^}
- return
- }
- }
- }
- backSpace
- }
-
- # bind delete key:
- ascii 0x08 escapeSmartStuff "TeX"
-
- #--------------------------------------------------------------------------
- # Smart paragraph filling:
- #--------------------------------------------------------------------------
-
- ##
- # Implements a more sophisticated fillParagraph function, which deals
- # with pre-indented paragraphs. Thus it won't wreck visually formatted
- # text files (such as itemised lists and equations in LaTeX files).
- ##
-
- ##
- # Known bugs:
- #
- # Filling a large paragraph which overlaps the top of the
- # screen causes a re-draw error, in which the whole paragraph
- # is draw in the on-screen window when some of it should not
- # be visible. Thus it appears to over-write some of the text
- # below. Fortunately this is an illusion (scroll up and down
- # a page and all is ok). This is a bug in Alpha's 'replaceText'
- # routine.
- #
- ##
-
- ##
- # Currently the following commands in LaTeX signify a new paragraph:
- #
- # "begin|end|(protect\)label|(sub)*section|centerline|paragraph|chapter|item|bibitem|intertext"
- #
- # as well as a blank line, '$$', and '\\'
- ##
-
- bind 'i' <c> texFillParagraph "TeX"
-
- proc texFillParagraph {} {
- if {[getPos] == [selEnd]} {
- fillOneParagraph
- } else {
- set start [getPos]
- set end [selEnd]
- set p $start
- while { $p < $end } {
- goto $p
- set p [texFillParagraph]
- }
- goto $start
- }
- }
-
- proc fillOneParagraph {} {
- global leftFillColumn fillColumn
-
- getWinInfo a
- set tabs $a(tabsize)
-
- set pos [getPos]
- # find nearest text to grab hold of
- # to try and maintain cursor position
- if { [lookAt $pos] != " " } {
- set grab [getText $pos [expr $pos +20]]
- set grabdiff 0
- } else {
- backwardWord
- set p2 [getPos]
- set grab [getText $p2 [expr $pos +20]]
- set grabdiff [expr $pos - $p2]
- }
-
- set start [paraStart $pos]
- set end [paraFinish $pos]
- # get the leading whitespace of the current line
- set res [search -s -n -f 1 -r 1 "^\[ \t\]*" [lineStart $pos]]
-
- # convert it to minimal form: tabs then spaces, stored in 'front'
- set sp [string range " " 1 $tabs ]
- regsub -all $sp [eval getText $res] "\t" front
- regsub -all "\[ \]+\t" $front "\t" front
- # get the length of the indent
- regsub -all "\t" $front $sp lfront
- set left [string length $lfront]
-
- # fill the text
- regsub -all "\[ \t\r\]+" [string trim [getText $start $end]] " " text
- # turn single spaces at end of sentences into double
- # regsub -all {(([^A-Z@]|\\@)[.?!]) } $text {\1 } text
- # regsub -all {(([^A-Z@]|\\@)[.?!]([])]|'|'')?) } $text {\1 } text
- regsub -all {(([^A-Z@]|\\@)[.?!][])']?) } $text {\1 } text
-
- # temporarily adjust the fillColumns
- set ol $leftFillColumn
- set or $fillColumn
- set leftFillColumn 0
- set fillColumn [expr $fillColumn - $left]
-
- # break and indent the paragraph
- regsub -all "\r" "\r[string trimright [breakIntoLines $text]]" "\r${front}" text
-
- # don't replace if nothing's changed
- if { "$text\r" != "\r[getText $start $end]" } {
- replaceText $start $end "[string range "$text" 1 end]\r"
- set p [fillFind $text $grab]
- if { $p == -1 } {
- goto $pos
- } else {
- goto [expr $start + $p + $grabdiff -1]
- }
- }
-
- set leftFillColumn $ol
- set fillColumn $or
- # in case we wish to fill a region
- return $end
- }
-
- proc fillFind { text search } {
- if { ![string length $search] } {
- return -1
- }
-
- set pos [string first $search $text]
- if { $pos != -1 } {
- return $pos
- } else {
- set search [string range $search 0 [expr [string length $search] -5]]
- return [fillFind $text $search]
- }
- }
-
- proc paraStart {pos} {
- global mode
- if {$pos == [maxPos]} {incr pos -1}
- set pos [lineStart $pos]
- if { $mode == "TeX" || $mode == "Bib" } {
- set paraCommands {begin|end|(protect\\)?label|(sub)*section|paragraph|centerline|caption|chapter|item|bibitem|intertext}
- set startPara {(\\\\[ \t]*$|^[ \t]*(\$\$[ \t]*|(%+.*|(\\(}
- append startPara $paraCommands {)(\[.*\]|\{.*\}|Ñ)*[ \t]*)+))?$)}
- } else {
- set startPara {^([ \t]*|([\\%].*))$}
- }
- set res [search -s -n -f 0 -r 1 -l 0 "$startPara" $pos]
- if {![string length $res] || $res == "0 0" } {return 0}
- if { [lindex $res 0] == $pos } {
- return $pos
- } else {
- return [nextLineStart [lindex $res 0]]
- }
-
- }
-
- proc paraFinish {pos} {
- global mode
- set pos [lineStart $pos]
- set end [maxPos]
- if { $mode == "TeX" || $mode == "Bib" } {
- set paraCommands {begin|end|(protect\\)?label|(sub)*section|paragraph|centerline|caption|chapter|item|bibitem|intertext}
- set endPara {^[ \t]*(\$\$[ \t]*|(%+.*|(\\(}
- append endPara $paraCommands {)(\[.*\]|\{.*\}|Ñ)*[ \t]*)+))?$}
- } else {
- set endPara {^([ \t]*|([\\%].*))$}
- }
-
- set res [search -s -n -f 1 -r 1 -l $end "$endPara" $pos]
- if {![string length $res]} {return $end}
- if { [lindex $res 0] == $pos } {
- return [nextLineStart $pos]
- }
- set res2 [search -s -n -f 1 -r 1 -l $end {\\\\[ \t]*$} $pos]
- if [string length $res2] {
- if { [lindex $res2 0] < [lindex $res 0] } {
- return [nextLineStart [lindex $res2 0]]
- }
- }
-
- return [lindex $res 0]
-
- }
-
-